home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Java 1996 August
/
Java - Summer 1996.iso
/
kaffe-0.2
/
kaffe
/
constants.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-12
|
5KB
|
237 lines
/*
* constants.c
* Constant management.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
*/
#define RDBG(s)
#include <stdio.h>
#include <assert.h>
#include "gtypes.h"
#include "constants.h"
#include "object.h"
#include "classMethod.h"
static strconst* strhash[STRHASHSZ];
static strpair* strpairhash[STRHASHSZ];
/*
* Read in constant pool from opened file.
*/
constants*
readConstantPool(classFile* fp)
{
constants* info;
u4* pool;
u1* tags;
int i;
u1 type;
u2 len;
strconst* c;
char* uc;
u1 d1;
u2 d2, d2b;
u4 d4;
info = (constants*)malloc(sizeof(constants));
if (info == 0) {
return (0);
}
readu2(&info->size, fp);
RDBG( printf("constant_pool_count=%d\n", info->size); )
/* Allocate space for tags and data */
pool = (u4*)malloc((sizeof(u4) + sizeof(u1)) * info->size);
if (pool == 0) {
return (0);
}
tags = (u1*)&pool[info->size];
info->data = pool;
info->tags = tags;
pool[0] = 0;
tags[0] = CONSTANT_Unknown;
for (i = 1; i < info->size; i++) {
readu1(&type, fp);
RDBG( printf("Constant type %d\n", type); )
tags[i] = type;
if (type == CONSTANT_Utf8) {
readu2(&len, fp);
c = (strconst*)malloc(sizeof(strconst) + len + 1);
if (c == 0) {
return (0);
}
readm(c->data, len, sizeof(u1), fp);
c->data[len] = 0;
RDBG( printf("Utf8=%s\n", c->data); )
pool[i] = (u4)addStringConstant(c);
}
else if (type == CONSTANT_Unicode) {
abort();
readu2(&len, fp);
uc = (u1*)malloc(len * 2 + 1);
readm(uc, len, sizeof(u2), fp);
uc[len * 2] = 0;
abort();
}
else switch (type) {
case CONSTANT_Class:
readu2(&d2, fp);
pool[i] = d2;
break;
case CONSTANT_String:
readu2(&d2, fp);
pool[i] = d2;
tags[i] = CONSTANT_Chararray;
break;
case CONSTANT_Fieldref:
case CONSTANT_Methodref:
case CONSTANT_InterfaceMethodref:
case CONSTANT_NameAndType:
readu2(&d2, fp);
readu2(&d2b, fp);
pool[i] = (d2b << 16) | d2;
break;
case CONSTANT_Integer:
case CONSTANT_Float:
readu4(&d4, fp);
pool[i] = d4;
break;
case CONSTANT_Long:
case CONSTANT_Double:
/* NON-PORTABLE!!! */
readu4(&d4, fp);
pool[i+1] = d4;
tags[i+1] = CONSTANT_Unknown;
readu4(&d4, fp);
pool[i] = d4;
i++;
break;
default:
fprintf(stderr, "Bad constant %d\n", type);
return (0);
}
}
/* Now create any string pairs required and any string objects */
for (i = 0; i < info->size; i++) {
if (tags[i] == CONSTANT_NameAndType) {
assert(tags[NAMEANDTYPE_NAME(i, info)] == CONSTANT_Utf8);
assert(tags[NAMEANDTYPE_SIGNATURE(i, info)] == CONSTANT_Utf8);
addStringConstantPair((char*)pool[NAMEANDTYPE_NAME(i, info)], (char*)pool[NAMEANDTYPE_SIGNATURE(i, info)]);
}
}
return (info);
}
/*
* Add a string to the string pool.
* If already there, free the new one and return the old one.
*/
char*
addStringConstant(strconst* s)
{
strconst* ptr;
uint32 hash;
int i;
for (hash = 0,i = 0; s->data[i] != 0; i++) {
hash = hash * 33 + s->data[i];
}
hash %= STRHASHSZ;
for (ptr = strhash[hash]; ptr != 0; ptr = ptr->next) {
if (strcmp(ptr->data, s->data) == 0) {
free(s);
return (ptr->data);
}
}
s->next = strhash[hash];
s->string = 0;
s->obj.mtable = 0;
s->obj.idx = 0;
s->obj.size = i;
s->obj.type = 0;
strhash[hash] = s;
return (s->data);
}
/*
* Add string pair to the pool.
*/
strpair*
addStringConstantPair(char* s1, char* s2)
{
uint32 hash;
int i;
strpair* ptr;
hash = 0;
for (i = 0; s1[i] != 0; i++) {
hash = hash * 33 + s1[i];
}
for (i = 0; s2[i] != 0; i++) {
hash = hash * 33 + s2[i];
}
for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
if (ptr->s1 == s1 && ptr->s2 == s2) {
return (ptr);
}
}
ptr = (strpair*)malloc(sizeof(strpair));
if (ptr == 0) {
return (0);
}
ptr->next = strpairhash[hash % STRHASHSZ];
ptr->hash = hash;
ptr->s1 = s1;
ptr->s2 = s2;
strpairhash[hash % STRHASHSZ] = ptr;
return (ptr);
}
/*
* Lookup a string pair in the pool.
*/
strpair*
lookupStringPair(char* s1, char* s2)
{
uint32 hash;
int i;
strpair* ptr;
hash = 0;
for (i = 0; s1[i] != 0; i++) {
hash = hash * 33 + s1[i];
}
for (i = 0; s2[i] != 0; i++) {
hash = hash * 33 + s2[i];
}
for (ptr = strpairhash[hash % STRHASHSZ]; ptr != 0; ptr = ptr->next) {
if (ptr->s1 == s1 && ptr->s2 == s2) {
return (ptr);
}
}
return (0);
}